/* 
 * Copyright 2011 Carnegie Mellon University
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package edu.cmu.lti.dimple;

import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import edu.cmu.lti.dimple.data.Pair;
import edu.cmu.lti.dimple.mavuno.LearnedParaphrases;
import edu.cmu.lti.dimple.mavuno.MavunoUtil;
import edu.cmu.lti.dimple.mavuno.PerTermParaphraser;
import edu.cmu.lti.dimple.nlp.SnowballStemmer;

/**
 * A class that experiments in matching text pairs (same meaning with 
 * different surface) using a paraphrase resource.   
 * 
 * @author Hideki Shima
 *
 * @param <T>
 */
public class PairMatchingEvaluation<T extends Pair> {

  public List<Double> evaluate( List<LearnedParaphrases> lps, 
          String targetTerm, List<T> pairs, String id, int listSize ) {

    List<Double> result = new ArrayList<Double>();
    
    StringBuilder log = new StringBuilder();
    for ( LearnedParaphrases lp : lps ) {
      int correct = 0;
      Pattern pTarget = Pattern.compile("\\b("+targetTerm+")\\b");
      PerTermParaphraser ptp = lp.get(targetTerm);
      if (ptp==null || ptp.getParaphrases()==null || ptp.getParaphrases().size()==0){
        System.out.println("No paraphrase available: "+lp.getAlgorighm()+" for "+targetTerm);
        continue;
      }
      List<String> terms = new ArrayList<String>();
      terms.add(targetTerm);
      terms.addAll(ptp.getParaphrases());
      Pattern pParaphrase = MavunoUtil.createPattern(terms, lp.getAlgorighm(), listSize+1, true);
      if (pParaphrase==null) continue;
      
      for ( T pair : pairs ) {
        boolean p1Hit1 = pTarget.matcher(pair.getText1()).find();
        boolean p1Hit2 = pTarget.matcher(pair.getText2()).find();
        boolean p2Hit1 = pParaphrase.matcher(pair.getText1()).find();
        boolean p2Hit2 = pParaphrase.matcher(pair.getText2()).find();
        if ( p1Hit1 && p2Hit2 || p2Hit1 && p1Hit2 ) {
          correct++;
        } else {
          boolean m = matchesAfterStemming(pair, targetTerm);
          if (m) {
            correct++;
          }
        }
      }
      double acc = (double) correct / (double) pairs.size();
      result.add(acc);
      log.append(targetTerm+" "+lp.getAlgorighm()+": "+correct+" / "+pairs.size() + " = "+acc+"\n" );
    }
    FileUtils.writeFile( log.toString(), new File("target/logs/"+id+"_eval.txt") );

    StringBuilder sb = new StringBuilder();
    for ( int i=0; i<pairs.size(); i++ ) {
      T pair = pairs.get(i);
      sb.append((i+1)+" ----\n");
      sb.append(pair.getText1()+"\n");
      sb.append(pair.getText2()+"\n");
    }
    FileUtils.writeFile( sb.toString(), new File("target/logs/"+id+"_pairs.txt") );
    return result;
  }
  
  private boolean matchesAfterStemming( T pair, String targetTerm ) {
    String[] w1 = pair.getText1().split("[^a-zA-Z]+");
    String[] w2 = pair.getText2().split("[^a-zA-Z]+");
    Set<String> roots1 = new HashSet<String>();
    Set<String> roots2 = new HashSet<String>();
    String root = SnowballStemmer.stem(targetTerm);
    for (String w : w1) {
      roots1.add(SnowballStemmer.stem(w));
    }
    for (String w : w2) {
      roots2.add(SnowballStemmer.stem(w));
    }
    return (roots1.contains(root) && roots2.contains(root));
  }
  
}
